﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Autofac;
using Autofac.Builder;
using Autofac.Core;
using Autofac.Features.Scanning;
using Core.Events;
using Domain.Entities;
using Domain.Events;

namespace EventConsoleApplication1
{
    public class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("==================方式一======================");
            First.Run();
            Console.WriteLine("==================方式二======================");
            Second.Run();
            /* var orderService = new OrderService();
             orderService.OrderCreated += (s,e) => new EmailService().SendMail(e.OrderNo);
             orderService.OrderCreated += (s, e) => new SmsService().SendSms(e.OrderNo);
             orderService.CreateOrder();*/
            Console.WriteLine("==================方式三======================");
            Init2();

            OrderEntity entity = new OrderEntity()
            {
                OrderNo = "XS" + DateTime.Now.ToString("yyyyMMddHHmmssfff")
            };

            entity.Created();

            Console.ReadLine();
        }

        #region 方法一注册事件
        /// <summary>
        /// 方法一注册事件
        /// </summary>
        private static void Init()
        {
            var handler = new OrderEventSendEmailHandler();
            var handler1 = new OrderEventSendEmailHandler();
            var handler2 = new OrderEventSendTestHandler();
            var handler3 = new OrderEventSendLogHandler();

            EventBus.Instance.Subscribe(handler, handler1, handler2, handler3);
        } 
        #endregion

        #region 方法二注册事件
        /// <summary>
        /// 方法二注册事件
        /// </summary>
        private static void Init2()
        {
            var builder = new ContainerBuilder();

            //将当前程序集注册到autofac容器
            RegisterAssemblyTypes(builder, typeof(IEventHandler<>), null);

            //注册订单创建事件
            RegisterEvent<OrderCreatedEvent>(builder);
        }

        /// <summary>
        /// 初始化事件订阅
        /// </summary>
        /// <typeparam name="TEvent">事件</typeparam>
        /// <param name="builder"></param>
        private static void RegisterEvent<TEvent>(ContainerBuilder builder) where TEvent : BaseEvent
        {
            var container = builder.Build();
            var allKeys = new List<object>();

            var allUnKeyedServices = new List<IEventHandler<TEvent>>(container.Resolve<IEnumerable<IEventHandler<TEvent>>>());

            allUnKeyedServices.AddRange(allKeys.Select(container.ResolveKeyed<IEventHandler<TEvent>>));

            EventBus.Instance.Subscribe(allUnKeyedServices);
        }

        public static void RegisterAssemblyTypes(ContainerBuilder containerBuilder, Type baseType, params Assembly[] assemblies)
        {
            if (assemblies == null ||
                assemblies.Length.Equals(0))
            {
                //测试项目时使用
                assemblies = AppDomain.CurrentDomain.GetAssemblies();
            }

            IRegistrationBuilder<object, ScanningActivatorData, DynamicRegistrationStyle> builder =
                containerBuilder.RegisterAssemblyTypes(assemblies);

            if (baseType != null)
            {
                if (baseType.IsGenericType)
                {
                    builder.Where(t => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == baseType)).AsImplementedInterfaces().PropertiesAutowired();
                }
                else
                {
                    builder.Where(t => baseType.IsAssignableFrom(t) && t != baseType).AsImplementedInterfaces().PropertiesAutowired();
                }
            }
        } 
        #endregion
    }
}


